<template>
  <div>
    <div style="position: absolute;top:10px;left:40%;z-index: 100">
      <audio id='myAudio' controls>
        <source src="/static/videos/music.mp3" type="audio/mp3">
      </audio>
    </div>
    <div id="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three'
import {OrbitControls} from "three/addons/controls/OrbitControls";

export default {
  name: "music-example",
  data() {
    return{
      scene:null,
      camera: null,
      renderer: null,
      boxMeshs: [],
      container:null,
      controls:null,
      myAudio:null,
      analyser:null,
      dataArray:[],
      source:null,
    }
  },
  methods:{
    initScene(){
      this.scene = new THREE.Scene();
    },
    initCamera(){
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
      this.camera.position.set(200,400,200);
    },
    initLight(){
      //添加两个平行光
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight1.position.set(300,300,300)
      this.scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight2.position.set(-300,300,300)
      this.scene.add(directionalLight2);
      const directionalLight3 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight3.position.set(-300,300,-300)
      this.scene.add(directionalLight3);
      const directionalLight4 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight4.position.set(-300,300,-300)
      this.scene.add(directionalLight4);
    },
    initFloor(){
      let floorGeometry = new THREE.BoxGeometry( 200,1,200);
      let floorMaterial = new THREE.MeshBasicMaterial({color:'#3399CC'});
      let floor = new THREE.Mesh( floorGeometry, floorMaterial );
      floor.position.set(0,2,0)
      this.scene.add(floor)
    },
    initRound(){
      const AudioContext = window.AudioContext || window.webkitAudioContext;
      let audioCtx = new AudioContext();
      if(!this.source){
        this.source = audioCtx.createMediaElementSource(this.myAudio);//通过audio标签获取播放源
        this.analyser = audioCtx.createAnalyser(); // 创建AnalyserNode 用于分析音频频谱的节点
        this.source.connect(this.analyser);
        this.analyser.connect(audioCtx.destination);
        let bufferLength = this.analyser.frequencyBinCount;
        this.dataArray = new Uint8Array(bufferLength);
      }
    },
    initBox(){
      let x = -60; let z = -60;
      for (let i = 0; i < 121; i++) {
        if(i%11 === 0){
          x = x + 11
          z = -60
        }
        z = z + 11
        const geometry = new THREE.BoxGeometry(10, 10, 10);
        const material = new THREE.MeshPhongMaterial({
          color: '#3399CC'
        });
        let boxMesh = new THREE.Mesh(geometry, material);
        this.boxMeshs.push(boxMesh)
        this.boxMeshs[i].position.set(x, 0, z);
        this.scene.add(this.boxMeshs[i]);
      }
    },
    initRenderer(){
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.container = document.getElementById("container")
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.renderer.setClearColor('#99FFCC', 1.0);
      this.container.appendChild(this.renderer.domElement);
    },
    initControl(){
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.maxPolarAngle = Math.PI / 2.2;      // // 最大角度
    },

    initAnimate() {
      requestAnimationFrame(this.initAnimate);
      this.renderer.render(this.scene, this.camera);
      if(this.analyser){
        this.analyser.getByteFrequencyData(this.dataArray);
        for (let i = 0; i < this.dataArray.length-1; i++) {
          if(this.boxMeshs[i]){
            let x = this.boxMeshs[i].position.x
            let z = this.boxMeshs[i].position.z
            this.boxMeshs[i].position.set(x,this.dataArray[i],z)
            this.boxMeshs[i].geometry.parameters.width = this.dataArray[i]
            this.boxMeshs[i].material.color = new THREE.Color(0.8,this.dataArray[i],this.dataArray[i]);
            let r =51, g = 153, b  = 204;
            if(this.dataArray[i]<85){
              r = g = b = this.dataArray[i] * 3
            }else if(this.dataArray[i]<170){
              r = g = (this.dataArray[i] - 85) * 2
              b = 255
            }else{
              r = (this.dataArray[i] - 170) * 3
              g = b = 255
            }
            this.boxMeshs[i].material.color = new THREE.Color('rgb('+r+', '+g+', '+b+')')
          }
        }
      }
    },
    initPage(){
      this.initScene();
      this.initCamera();
      this.initLight();
      this.initFloor();
      this.initRenderer();
      this.initControl();
      this.initBox();
      this.initAnimate();
    }
  },
  mounted() {
    this.myAudio = document.querySelector('#myAudio');
    this.myAudio.addEventListener('play', () => {
      this.initRound();
    })
    this.initPage()
  }
}
</script>

<style>
#container{
  position: absolute;
  width:100%;
  height:100%;
  overflow: hidden;
}

</style>
